﻿namespace Busconeitor.BusinessLayer.Util
{
    using System.Collections.Generic;
    using System.Collections;
    using System.Linq;
    using System.Text;

    public static class TratamientoTexto
    {
        /*
        * Este vector contiene los caracteres que se van a limpiar de un texto, por un espacio en blanco
        * En el caso de las letras acentuadas, se le quitan los acentos a las mismas
        */
        private static Dictionary<string, string> caracteresLimpiar = new Dictionary<string, string>();

        /// <summary>
        /// Este vector, contiene los caracteres que se van a estandarizar, de un texto en cuestión
        /// </summary>
        private static Dictionary<string, string> caracteresEstandarizar = new Dictionary<string, string>();

        private static Hashtable hashPalabrasVacias = new Hashtable();

        /// <summary>
        /// Este vector, contiene las palabras vacías o Stop Words, que se van a descartar
        /// a la hora de la indexación.
        /// Se incluye: preposiciones , adverbios, artículos , conjunciones, distributivos, indefinidos,
        /// interjecciones, numerales, posesivos, pronombres
        /// </summary>
        private static string[] palabrasVacias = new string[]
        {
        "a", "al", "asi", "aun", "aca", "ademas", "ahi", "ahora", "alguien", "alguna", "algunas", "alguno", "algunos", "alla", "ambos", "ambas", "antes", "aquel", "aquellos", "aquella", "aquellas", "aqui", "ago", "ante", "alli", "aunque", "ay", "aupa", "adios",
        "bien", "bueno", "bajo",
        "cabe", "causa", "cierta", "cierto", "ciertos", "cinco", "con", "como", "consecuentemente", "constante", "constantemente", "contra", "com", "cuan", "cuanto", "cuanta", "cuantas", "cuantos", "cualquiera", "cuatro", "cual", "cerca", "cuando", "cortesmente", "casi", "conque", "cada", "cualquier", "cielos", "cuyo",
        "dar", "de", "del", "donde", "deprisa", "desde", "despacio", "despues", "dificil", "dio", "dos", "durante", "demasiado", "doble",
        "el", "ellos", "es", "en", "este", "esta", "esto", "estas", "estos", "eso", "esa", "esos", "esas", "ese", "ellas", "ella", "era", "ello", "entre", "efectivamente", "exclusive", "excepto", "e", "ea",
        "facil", "facilmente", "frecuentemente", "fue",
        "ha", "habitual", "habitualmente", "hacia", "halla", "has", "hasta", "hay", "hoy", "hola",
        "ir", "instante", "instantes", "incluso", "inclusive",
        "jamas",
        "la", "las", "le", "les", "lo", "los", "luego",
        "mal", "mas", "me", "mediante", "medio", "menos", "mes", "mitad", "mi", "mios", "mientras", "mis", "misma", "mismo", "mismos", "modo", "momento", "momentos", "mucha", "muchas", "mucho", "muy",
        "n°", "nada", "nadie", "ni", "ningun", "ninguno", "no", "nos", "nosotros", "nuestra", "nuestro", "nuestros", "nunca", "nosotras",
        "otro", "otra", "otros", "otras", "obstante", "ojala", "o", "oh", "os",
        "para", "pese", "pero", "porque", "poca", "pocas", "poco", "pocos", "por", "pleno", "proposito", "pronto", "pro", "posiblemente", "primeramente", "pues", "primero",
        "que", "quien", "quizas", "quiza", "quienes",
        "respecto", "respectivamente", "referente", "recien",
        "segun", "seis", "se", "ser", "si", "sin", "solamente", "sobre", "son", "suya", "suyas", "suyo", "suyos", "su", "sus", "salvo", "sino", "sendos",
        "tantos", "tanto", "tanta", "tantas", "tan", "tambien", "tal", "te", "todo", "toda", "todos", "todas", "tu", "tuya", "tuyas", "tuyo", "tuyos", "tras", "traves", "tres", "ti",
        "uno", "unos", "unas", "un", "una", "usted", "ustedes", "u", "uy",
        "va", "van", "varios", "varias", "ve", "venir", "venimos", "vino", "vos", "via", "venga", "vosotros", "vosotras",
        "y", "ya", "yo"
        };

        private static void CargarCaracteresLimpiar()
        {
            caracteresLimpiar.Add(",", " ");
            caracteresLimpiar.Add(".", " ");
            caracteresLimpiar.Add(";", " ");
            caracteresLimpiar.Add("'", "");
            caracteresLimpiar.Add("(", " ");
            caracteresLimpiar.Add(")", " ");
            caracteresLimpiar.Add("[", " ");
            caracteresLimpiar.Add("]", " ");
            caracteresLimpiar.Add("-", " ");
            caracteresLimpiar.Add("+", " ");
            caracteresLimpiar.Add("¡", " ");
            caracteresLimpiar.Add("!", " ");
            caracteresLimpiar.Add("á", "a");
            caracteresLimpiar.Add("é", "e");
            caracteresLimpiar.Add("í", "i");
            caracteresLimpiar.Add("ó", "o");
            caracteresLimpiar.Add("ú", "u");
            caracteresLimpiar.Add(":", " ");
            caracteresLimpiar.Add("\"", " ");
            caracteresLimpiar.Add("%", " ");
            caracteresLimpiar.Add("$", " ");
            caracteresLimpiar.Add("¿", " ");
            caracteresLimpiar.Add("?", " ");
            caracteresLimpiar.Add("0", " ");
            caracteresLimpiar.Add("1", " ");
            caracteresLimpiar.Add("2", " ");
            caracteresLimpiar.Add("3", " ");
            caracteresLimpiar.Add("4", " ");
            caracteresLimpiar.Add("5", " ");
            caracteresLimpiar.Add("6", " ");
            caracteresLimpiar.Add("7", " ");
            caracteresLimpiar.Add("8", " ");
            caracteresLimpiar.Add("9", " ");
            caracteresLimpiar.Add("&#", " ");
            caracteresLimpiar.Add("?", " ");
            caracteresLimpiar.Add("<i>", " ");
            caracteresLimpiar.Add("</i>", " ");
            caracteresLimpiar.Add("<p>", " ");
            caracteresLimpiar.Add("</p>", " ");
            caracteresLimpiar.Add("</b>", " ");
            caracteresLimpiar.Add("<b>", " ");
            caracteresLimpiar.Add("°", " ");
            caracteresLimpiar.Add("&", " ");
            caracteresLimpiar.Add("ª", " ");
        }

        private static void CargarCaracteresEstandarizar()
        {
            caracteresEstandarizar.Add("Ã¡", "á");
            caracteresEstandarizar.Add("Ã©", "é");
            caracteresEstandarizar.Add("Ã", "í");
            caracteresEstandarizar.Add("Ã³", "ó");
            caracteresEstandarizar.Add("Ãº", "ú");
            caracteresEstandarizar.Add("í³", "ó");
            caracteresEstandarizar.Add("í±", "ñ");
            caracteresEstandarizar.Add("í³", "ó");
            caracteresEstandarizar.Add("íº", "ú");
            caracteresEstandarizar.Add("&quot;", "\"");
            caracteresEstandarizar.Add("&iacute;", "í");
            caracteresEstandarizar.Add("&oacute;", "ó");
            caracteresEstandarizar.Add("&oecute;", "é");
            caracteresEstandarizar.Add("&eacute;", "é");
            caracteresEstandarizar.Add("&aacute;", "á");
            caracteresEstandarizar.Add("&oucute;", "ú");
            caracteresEstandarizar.Add("&oucute;", "ú");
            caracteresEstandarizar.Add("&uacute;", "ú");
            caracteresEstandarizar.Add("&ntilde;", "ñ");
        }

        /// <summary>
        /// Esta función, para una cadena, recorre el vector de caracteres a limpiar, y la reemplaza
        /// por el correspondiente valor, en caso de encontrarse la misma
        /// </summary>
        /// <param name="entrada"></param>
        /// <param name="caracteresLimpiar"></param>
        /// <returns></returns>
        private static string LimpiarTextoSignosPuntuacion(string entrada)
        {
            for (var i = 0; i < caracteresLimpiar.Count; i++)
            {
                entrada = entrada.Replace(caracteresLimpiar.Keys.ElementAt(i), caracteresLimpiar.Values.ElementAt(i));
            }

            return entrada;
        }

        /// <summary>
        /// Esta función, para una cadena, recorre el vector de caracteres a estandarizar, y la reemplaza
        /// por el correspondiente valor, en caso de encontrarse la misma
        /// </summary>
        /// <param name="entrada"></param>
        /// <returns></returns>
        private static string EstandarizarTexto(string entrada)
        {
            for (var i = 0; i < caracteresEstandarizar.Count; i++)
            {
                entrada = entrada.Replace(caracteresEstandarizar.Keys.ElementAt(i), caracteresEstandarizar.Values.ElementAt(i));
            }

            return entrada;
        }

        /// <summary>
        /// Esta función se encarga de quitar de un texto, las palabras stop Words,
        /// Estas se obtienen del vector palabrasVacias y retorna el nuevo texto, sin las palabras vacias
        /// </summary>
        /// <param name="texto"></param>
        /// <returns></returns>
        public static string EliminarPalabrasVacias(string texto)
        {
            var nuevoTexto = new StringBuilder();
            var textIntermedio = texto.Split(' ');

            RealizarHashPalabrasVacias();

            foreach (var palabra in textIntermedio)
            {
                if (!EsPalabraVacia(palabra))
                {
                    nuevoTexto.Append(palabra + " ");
                }
            }

            return nuevoTexto.ToString();
        }

        /// <summary>
        /// Esta función determina el tamaño de una palabra, y si es de uno, la marca como palabra vacía
        /// </summary>
        /// <param name="palabra"></param>
        /// <returns></returns>
        public static bool EsPalabraVacia(string palabra)
        {
            var esPalabraVacia = false;

            //si la palabra tiene longitud igual a uno retorna true
            if (palabra.Length == 1)
            {
                esPalabraVacia = true;
            }
            else
            {
                if (hashPalabrasVacias.ContainsKey(palabra))
                {
                    esPalabraVacia = true;
                }
            }

            return esPalabraVacia;
        }

        /// <summary>
        /// Esta función recorre el vector de palabras vacías y le realiza un hash
        /// </summary>
        public static void RealizarHashPalabrasVacias()
        {
            if (hashPalabrasVacias.Count == 0)
            {
                foreach (var t in palabrasVacias)
                {
                    hashPalabrasVacias.Add(t, "");
                }
            }
        }

        /// <summary>
        /// Esta función se utiliza para estandarizar los caracteres del texto, correspondiente al título de una noticia
        /// </summary>
        /// <param name="tituloDocumento">un String, que representa el texto del título de la noticia original</param>
        /// <returns>un String, que representa el texto del título de la noticia, con los caracteres estandarizados</returns>
        public static string TratarTituloDocumento(string tituloDocumento)
        {
            tituloDocumento = EstandarizarTexto(tituloDocumento);

            return tituloDocumento;
        }
    }
}
